package com.webssh.service.handler.terminal;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import com.alibaba.fastjson.JSONObject;
import com.jcraft.jsch.JSchException;
import com.webssh.service.handler.HandlerProcess;

public class TerminalHandler implements HandlerProcess {

	private static Logger logger = LoggerFactory.getLogger(TerminalHandler.class);
	
	private static final String resize = "action_resize.do:";
	private static final String sendAll = "action_sendAll.do:";
	private static final String upload = "action_uploadFile.do:";
	
	private static final Set<String> actions = new HashSet<String>();
	
	static{
		actions.add(resize);
		actions.add(sendAll);
		actions.add(upload);
	}
	
	private WebSocketSession session;
	
	public TerminalHandler(WebSocketSession session) throws IOException {
		this.session = session;
	}


	@Override
	public void close() throws IOException {
//		String sshSessionId = (String) session.getAttributes().get(SSH_SESSION_ID);
//		if (sshSessionId != null) {
//			TerminalContext.remove(sshSessionId);
//		}
		TerminalClient terminalClient = TerminalSession.remove(session);
		if (terminalClient != null && !terminalClient.isClosed()) {
			terminalClient.disconnect();
		}
		if(session !=null && session.isOpen()){
			session.close();
		}
	}

	@Override
	public void handleMessage(String string) throws IOException {
		if(StringUtils.isNotEmpty(string)){
			boolean action = isActions(string);
			TerminalClient terminalClient = TerminalSession.get(session);
			if (terminalClient != null ) {
				try {
					if (!terminalClient.isClosed()) {
						if(action){
							if(string.startsWith(resize)){
								JSONObject json = JSONObject.parseObject(string.replace(resize, ""));
								terminalClient.resize(json.getInteger("cols"), json.getInteger("rows"),
										json.getInteger("width"), json.getInteger("height"));
							}else if(string.startsWith(sendAll)){
								String cmd = URLDecoder.decode(string.replace(sendAll, ""), "UTF-8");
								boolean enter = false;
								if(cmd.endsWith("\\r")){
									enter = true;
									cmd = cmd.substring(0, cmd.lastIndexOf("\\r"));
								}
								String httpSessionId = (String) session.getAttributes().get(HttpSessionHandshakeInterceptor.HTTP_SESSION_ID_ATTR_NAME);
								List<TerminalClient> list = TerminalSession.findClient(httpSessionId);
								for(TerminalClient t: list){
									t.write(cmd);
									if(enter)t.write("\r");
								}
							}else if(string.startsWith(upload)){
								terminalClient.setUploadFileToken(string.replace(upload, ""));
							}
						}else{
							terminalClient.write(string);
						}
					}else {
						this.close();
					}
				} catch (Exception e) {
					session.sendMessage(new TextMessage("Sorry! exception occurred: " + e.getMessage() + ". jSch Terminal was closed, please try again.\r\n"));
					terminalClient.disconnect();
					this.close();
				}
			}else{
				if(action && string.startsWith(resize))return;
				this.close();
			}
		}
	}
	
	private boolean isActions(String string){
		for(String action: actions){
			if(string.startsWith(action))return true;
		}
		return false;
	}

	@Override
	public void init() throws IOException {
		session.sendMessage(new TextMessage("Welcome to jSch Terminal! Connect Starting...\r\n"));
		if(session.getAttributes().get("openNew") == null){
			String httpSessionId = (String) session.getAttributes().get(HttpSessionHandshakeInterceptor.HTTP_SESSION_ID_ATTR_NAME);
			Terminal terminal = TerminalSession.findConnectedTerminalClient(httpSessionId);
			if(terminal != null){
				logger.debug("当前会话已有登陆成功链接，直接链接ssh");
				try {
					new TerminalClient(terminal.copy()).init(session);
				} catch (JSchException e) {
					logger.error(e.getMessage(), e);
					session.sendMessage(new TextMessage("Sorry! Operation error(" + e.getMessage() +"), please try again.\r\n"));
					this.close();
				}
			}else{
				logger.debug("该会话无登陆成功链接，需登陆ssh");
				session.sendMessage(new TextMessage(">>Please login!\r\n\r\n"));//>>Please login!
			}
		}else{
			logger.debug("新窗口，需登陆ssh");
			session.sendMessage(new TextMessage(">>Please login!\r\n\r\n"));//>>Please login!
		}
	}
}
